<template>
  <div class="app-container">
    <el-dialog
      :title="textMap[dialogStatus]"
      :visible.sync="dialogFormVisible"
      width="800px"
    >
      <el-form
        ref="dataForm"
        :rules="rules"
        :model="temp"
        label-position="left"
      >
        <FormItems
          ref="formItems"
          :model-name="modelName"
          :dialog-status="dialogStatus"
          :form-items="formItems"
          :temp="temp"
          :configs="configs"
          @change="handleChange"
        />
      </el-form>
      <div slot="footer" class="dialog-footer">
        <el-button @click="dialogFormVisible = false">取消</el-button>
        <el-button
          type="primary"
          @click="dialogStatus === 'create' ? createData() : updateData()"
        >
          确认
        </el-button>
      </div>
    </el-dialog>
  </div>
</template>

<script>
import odoo from '@/odooapi'
import FormItems from './FormItems'

import { parseTime } from '@/utils'

// TBD  form item  change event
// 接收 选择框的 change 事件, 其他的 form item 的值 有关联关系

export default {
  name: 'FormDialog',
  components: { FormItems },
  directives: {},
  filters: {},

  props: {
    modelName: { type: String, default: '' },
    childFieldName: { type: String, default: undefined }
  },

  data() {
    return {
      Model: undefined,

      formItems: [],

      temp: {},

      dialogFormVisible: false,
      dialogStatus: '',
      textMap: {
        update: '修改',
        create: '添加'
      },
      rules: {
        // type: [{ required: true, message: 'type is required', trigger: 'change' }],
        // timestamp: [{ type: 'date', required: true, message: 'timestamp is required', trigger: 'change' }],
        // title: [{ required: true, message: 'title is required', trigger: 'blur' }]
      },
      configs: {},
      editMethod: 'write'
    }
  },

  watch: {},

  async created() {
    this.Model = odoo.env(this.modelName)
    if (this.childFieldName) {
      const { child_configs } = this.Model.configs

      const formItems = await this.Model.formOptions(
        child_configs[this.childFieldName].formItems,
        this.childFieldName
      )

      this.formItems = formItems

      const tempData = formItems.reduce(
        (acc, cur) => {
          // if (typeof cur.default === 'function') {
          //   acc[cur.name] = cur.default({ self: this.Model })
          // } else {
          //   acc[cur.name] = cur.default
          // }
          acc[cur.name] = cur.default
          return acc
        },
        { id: undefined }
      )

      this.tempData = tempData
      this.resetTemp()

      // this.temp = tempData || {}
    } else {
      const { formItems } = this.Model.configs

      const tempData = formItems.reduce(
        (acc, cur) => {
          acc[cur.name] = cur.default
          return acc
        },
        { id: undefined }
      )

      this.tempData = tempData
      this.resetTemp()
      //      this.temp = tempData || {}

      // 此时只能获取 静态的 formItems 的 select 的 options
      // 要动态获取, 需要把 row id 有关的数据 传入
      this.formItems = await this.Model.formOptions(formItems)
    }

    this.rules = this.formItems.reduce((acc, cur) => {
      const temp = {
        required: true,
        message: '请输入信息!',
        trigger: 'change'
      }

      if (['textarea', 'input', 'number'].includes(cur.type)) {
        temp.trigger = 'blur'
      }

      acc[cur.name] = [{ ...temp, ...(cur.rules || {}) }]
      return acc
    }, {})
  },

  methods: {
    handleChange(temp) {
      this.temp = { ...this.temp, ...temp }
    },
    resetTemp() {
      this.temp = Object.keys(this.tempData).reduce((acc, cur) => {
        const cc = this.tempData[cur]
        acc[cur] = typeof cc === 'function' ? null : cc
        return acc
      }, {})

      // this.temp = { ...this.tempData }
    },

    handleCreate(head_id, headData) {
      this.set_form_configs({})

      const formItems = this.formItems.reduce((acc, item) => {
        acc[item.name] = item
        return acc
      }, {})

      // for line form
      this.head_id = head_id
      this.headData = headData

      this.resetTemp()
      const new_temp = {}
      Object.keys(this.tempData).forEach(item => {
        if (typeof this.tempData[item] === 'function') {
          const value = this.tempData[item]({
            self: this.Model,
            headData,
            formItem: formItems[item]
          })
          new_temp[item] = value

          this.$nextTick(() => {
            this.$refs['formItems'].handleChange(value, formItems[item])
          })
        }
      })
      this.temp = { ...this.temp, ...new_temp }

      this.dialogStatus = 'create'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },

    set_form_configs(row) {
      const formItems = this.formItems.reduce((acc, item) => {
        acc[item.name] = item
        return acc
      }, {})

      this.configs = {
        handleHidden: (hidden, fi) => {
          // console.log('xxxxx,222, handleHidden', hidden)
          return hidden({ self: this.Model, temp: this.temp, items: formItems })
        },

        handleReadonly: (readonly, fi) => {
          // console.log('xxxxx,222, handleReadonly', readonly)
          return readonly({ self: this.Model })
        },

        get_options: fi => {
          // 在configs中定义了该函数, 返回 options
          // 该 options 与当前 form 中的数据有关
          return fi.options_for_select({
            self: this.Model,
            options_for_select: fi.options_for_select_init,
            row,
            temp: this.temp,
            items: formItems
          })
        }
      }
    },

    async handleUpdate(row, kwargs = {}) {
      const {
        head_id, // headData,
        method
      } = kwargs

      this.set_form_configs(row)

      this.editMethod = method || 'write'
      // this.update_method = method
      // console.log('xxxxxx, handleUpdate,', kwargs, method, this.editMethod)

      // for line form
      this.head_id = head_id

      this.temp = Object.keys(this.temp).reduce((acc, cur) => {
        acc[cur] = row[cur]
        return acc
      }, {})

      // Object.assign({}, row) // copy obj

      this.dialogStatus = 'update'
      this.dialogFormVisible = true
      this.$nextTick(() => {
        this.$refs['dataForm'].clearValidate()
      })
    },

    createData() {
      if (this.childFieldName) {
        this.createDataForLine()
      } else {
        this.createDataForHead()
      }
    },

    updateData() {
      if (this.childFieldName) {
        this.updateDataForLine()
      } else {
        this.updateDataForHaed()
      }
    },

    get_values() {
      const tempData = Object.assign({}, this.temp)
      this.formItems.forEach(item => {
        if (item.type === 'date') {
          const date = tempData[item.name]
          if (date) {
            tempData[item.name] = parseTime(date, '{y}-{m}-{d}')
          }
        } else if (item.type === 'date_month') {
          const date_month = tempData[item.name]
          if (date_month) {
            const new_date = `${parseTime(date_month, '{y}-{m}')}-01`
            tempData[item.name] = new_date
          }
        } else if (item.type === 'select' && !item.multiple) {
          const val = tempData[item.name]
          if (!val) {
            tempData[item.name] = null
          }
        } else if (item.type === 'select' && item.multiple) {
          tempData[item.name] = [[6, 0, tempData[item.name]]]
        }
      })

      return tempData
    },

    createDataForHead() {
      this.$refs['dataForm'].validate(async valid => {
        if (valid) {
          const tempData = this.get_values()

          this.Model.create(tempData).then(res => {
            // emit parent to get list
            // this.getList()
            this.$emit('created', res)
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '创建成功',
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },

    updateDataForHaed() {
      const method = this.editMethod || 'write'

      this.$refs['dataForm'].validate(async valid => {
        if (valid) {
          const tempData = this.get_values()

          this.Model[method](tempData).then(res => {
            // this.getList()
            this.$emit('changed', res)

            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '修改成功',
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },

    createDataForLine() {
      this.$refs['dataForm'].validate(async valid => {
        if (valid) {
          const tempData = this.get_values()

          delete tempData.id
          const vals = { id: this.head_id }
          vals[this.childFieldName] = [[0, 0, tempData]]

          this.Model.write(vals).then(res => {
            this.$emit('changed', this.childFieldName)

            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '创建成功',
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    },

    updateDataForLine() {
      this.$refs['dataForm'].validate(async valid => {
        if (valid) {
          const tempData = this.get_values()

          const chid = tempData.id
          delete tempData.id
          const vals = { id: this.head_id }
          vals[this.childFieldName] = [[1, chid, tempData]]

          this.Model.write(vals).then(res => {
            this.$emit('changed', this.childFieldName)
            this.dialogFormVisible = false
            this.$notify({
              title: '成功',
              message: '修改成功',
              type: 'success',
              duration: 2000
            })
          })
        }
      })
    }
  }
}
</script>
